home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / gnu / cvs-1_3.lha / cvs-1.3 / src / ignore.c < prev    next >
C/C++ Source or Header  |  1992-04-02  |  5KB  |  228 lines

  1. /*
  2.  * .cvsignore file support contributed by David G. Grubbs <dgg@ksr.com>
  3.  */
  4.  
  5. #include "cvs.h"
  6.  
  7. #ifndef lint
  8. static char rcsid[] = "@(#)ignore.c 1.13 92/04/03";
  9. #endif
  10.  
  11. /*
  12.  * Ignore file section.
  13.  * 
  14.  *    "!" may be included any time to reset the list (i.e. ignore nothing);
  15.  *    "*" may be specified to ignore everything.  It stays as the first
  16.  *        element forever, unless a "!" clears it out.
  17.  */
  18.  
  19. static char **ign_list;            /* List of files to ignore in update
  20.                      * and import */
  21. static char **s_ign_list = NULL;
  22. static int ign_count;            /* Number of active entries */
  23. static int s_ign_count = 0;
  24. static int ign_size;            /* This many slots available (plus
  25.                      * one for a NULL) */
  26. static int ign_hold;            /* Index where first "temporary" item
  27.                      * is held */
  28.  
  29. char *ign_default = ". .. core RCSLOG tags TAGS RCS SCCS .make.state .nse_depinfo #* .#* cvslog.* ,* CVS* .del-* *.a *.o *.so *.Z *~ *.old *.elc *.ln *.bak *.BAK *.orig *.rej";
  30.  
  31. #define IGN_GROW 16            /* grow the list by 16 elements at a
  32.                      * time */
  33.  
  34. /*
  35.  * To the "ignore list", add the hard-coded default ignored wildcards above,
  36.  * the wildcards found in $CVSROOT/CVSROOT/cvsignore, the wildcards found in
  37.  * ~/.cvsignore and the wildcards found in the CVSIGNORE environment
  38.  * variable.
  39.  */
  40. void
  41. ign_setup ()
  42. {
  43.     extern char *getenv ();
  44.     struct passwd *pw;
  45.     char file[PATH_MAX];
  46.     char *tmp;
  47.  
  48.     /* Start with default list and special case */
  49.     tmp = xstrdup (ign_default);
  50.     ign_add (tmp, 0);
  51.     free (tmp);
  52.  
  53.     /* Then add entries found in repository, if it exists */
  54.     (void) sprintf (file, "%s/%s/%s", CVSroot, CVSROOTADM, CVSROOTADM_IGNORE);
  55.     if (isfile (file))
  56.     ign_add_file (file, 0);
  57.  
  58.     /* Then add entries found in home dir, (if user has one) and file exists */
  59.     if ((pw = (struct passwd *) getpwuid (getuid ())) && pw->pw_dir)
  60.     {
  61.     (void) sprintf (file, "%s/%s", pw->pw_dir, CVSDOTIGNORE);
  62.     if (isfile (file))
  63.         ign_add_file (file, 0);
  64.     }
  65.  
  66.     /* Then add entries found in CVSIGNORE environment variable. */
  67.     ign_add (getenv (IGNORE_ENV), 0);
  68.  
  69.     /* Later, add ignore entries found in -I arguments */
  70. }
  71.  
  72. /*
  73.  * Open a file and read lines, feeding each line to a line parser. Arrange
  74.  * for keeping a temporary list of wildcards at the end, if the "hold"
  75.  * argument is set.
  76.  */
  77. void
  78. ign_add_file (file, hold)
  79.     char *file;
  80.     int hold;
  81. {
  82.     FILE *fp;
  83.     char line[1024];
  84.  
  85.     /* restore the saved list (if any) */
  86.     if (s_ign_list != NULL)
  87.     {
  88.     int i;
  89.  
  90.     for (i = 0; i < s_ign_count; i++)
  91.         ign_list[i] = s_ign_list[i];
  92.     ign_count = s_ign_count;
  93.     ign_list[ign_count] = NULL;
  94.  
  95.     s_ign_count = 0;
  96.     free (s_ign_list);
  97.     s_ign_list = NULL;
  98.     }
  99.  
  100.     /* is this a temporary ignore file? */
  101.     if (hold)
  102.     {
  103.     /* re-set if we had already done a temporary file */
  104.     if (ign_hold)
  105.     {
  106.         int i;
  107.  
  108.         for (i = ign_hold; i < ign_count; i++)
  109.         free (ign_list[i]);
  110.         ign_count = ign_hold;
  111.         ign_list[ign_count] = NULL;
  112.     }
  113.     else
  114.     {
  115.         ign_hold = ign_count;
  116.     }
  117.     }
  118.  
  119.     /* load the file */
  120.     if (!(fp = fopen (file, "r")))
  121.     return;
  122.     while (fgets (line, sizeof (line), fp))
  123.     ign_add (line, hold);
  124.     (void) fclose (fp);
  125. }
  126.  
  127. /* Parse a line of space-separated wildcards and add them to the list. */
  128. void
  129. ign_add (ign, hold)
  130.     char *ign;
  131.     int hold;
  132. {
  133.     if (!ign || !*ign)
  134.     return;
  135.  
  136.     for (; *ign; ign++)
  137.     {
  138.     char *mark;
  139.     char save;
  140.  
  141.     /* ignore whitespace before the token */
  142.     if (isspace (*ign))
  143.         continue;
  144.  
  145.     /*
  146.      * if we find a single character !, we must re-set the ignore list
  147.      * (saving it if necessary).  We also catch * as a special case in a
  148.      * global ignore file as an optimization
  149.      */
  150.     if (isspace (*(ign + 1)) && (*ign == '!' || *ign == '*'))
  151.     {
  152.         if (!hold)
  153.         {
  154.         /* permanently reset the ignore list */
  155.         int i;
  156.  
  157.         for (i = 0; i < ign_count; i++)
  158.             free (ign_list[i]);
  159.         ign_count = 0;
  160.         ign_list[0] = NULL;
  161.  
  162.         /* if we are doing a '!', continue; otherwise add the '*' */
  163.         if (*ign == '!')
  164.             continue;
  165.         }
  166.         else if (*ign == '!')
  167.         {
  168.         /* temporarily reset the ignore list */
  169.         int i;
  170.  
  171.         if (ign_hold)
  172.         {
  173.             for (i = ign_hold; i < ign_count; i++)
  174.             free (ign_list[i]);
  175.             ign_hold = 0;
  176.         }
  177.         s_ign_list = (char **) xmalloc (ign_count * sizeof (char *));
  178.         for (i = 0; i < ign_count; i++)
  179.             s_ign_list[i] = ign_list[i];
  180.         s_ign_count = ign_count;
  181.         ign_count = 0;
  182.         ign_list[0] = NULL;
  183.         continue;
  184.         }
  185.     }
  186.  
  187.     /* If we have used up all the space, add some more */
  188.     if (ign_count >= ign_size)
  189.     {
  190.         ign_size += IGN_GROW;
  191.         ign_list = (char **) xrealloc ((char *) ign_list,
  192.                        (ign_size + 1) * sizeof (char *));
  193.     }
  194.  
  195.     /* find the end of this token */
  196.     for (mark = ign; *mark && !isspace (*mark); mark++)
  197.          /* do nothing */ ;
  198.  
  199.     save = *mark;
  200.     *mark = '\0';
  201.  
  202.     ign_list[ign_count++] = xstrdup (ign);
  203.     ign_list[ign_count] = NULL;
  204.  
  205.     *mark = save;
  206.     if (save)
  207.         ign = mark;
  208.     else
  209.         ign = mark - 1;
  210.     }
  211. }
  212.  
  213. /* Return 1 if the given filename should be ignored by update or import. */
  214. int
  215. ign_name (name)
  216.     char *name;
  217. {
  218.     char **cpp = ign_list;
  219.  
  220.     if (cpp == NULL)
  221.     return (0);
  222.  
  223.     while (*cpp)
  224.     if (fnmatch (*cpp++, name, 0) == 0)
  225.         return (1);
  226.     return (0);
  227. }
  228.